﻿/*----------------------------------------------------------------
//  <copyright file="DashedRoutingConvention.cs" company="MicroCloud@151504200868">
//      Copyright © 2020-2024 MicroCloud Corporation, All rights reserved.
//  </copyright>
//  <site>https://gitee.com/chenmm123/microclouds</site>
//  <last-editor>cmm</last-editor>
//  <last-date>2022-11-15 11:02</last-date>
//----------------------------------------------------------------*/

namespace MicroCloud.AspNetCore.Mvc.Conventions
{
    #region "单词减号分隔符(AddUser -> add-user) URL转换器"
    /// <summary>
    /// 单词减号分隔符(AddUser -> add-user) URL转换器
    /// </summary>
    public class DashedRoutingConvention : IControllerModelConvention
    {
        #region "方法"
        #region "要求将公约适用于 <see cref="ControllerModel" />"
        /// <summary>
        /// 要求将公约适用于 <see cref="ControllerModel" />
        /// </summary>
        /// <param name="controller">The <see cref="ControllerModel" /></param>
        public void Apply(ControllerModel controller)
        {
            var hasRouteAttribute = controller.Selectors.Any(selector => selector.AttributeRouteModel != null);
            if (hasRouteAttribute)
            {
                return;
            }
            foreach (ActionModel action in controller.Actions)
            {
                foreach (SelectorModel model in action.Selectors.Where(m => m.AttributeRouteModel == null))
                {
                    List<string> parts = new List<string>();
                    foreach (var attribute in controller.Attributes)
                    {
                        if (attribute is AreaAttribute area)
                        {
                            parts.Add(PascalToKebabCase(area.RouteValue));
                            break;
                        }
                    }

                    if (parts.Count == 0 && controller.ControllerName == "Home" && action.ActionName == "Index")
                    {
                        continue;
                    }
                    parts.Add(PascalToKebabCase(controller.ControllerName));

                    if (action.ActionName != "Index")
                    {
                        parts.Add(PascalToKebabCase(action.ActionName));
                    }

                    string template = string.Join("/", parts);
                    model.AttributeRouteModel = new AttributeRouteModel() { Template = template };
                }
            }
        }
        #endregion

        #endregion

        #region "私有静态方法"
        #region "PascalToKebabCase"
        /// <summary>
        /// PascalToKebabCase
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        private static string PascalToKebabCase(string value)
        {
            if (string.IsNullOrEmpty(value))
            {
                return value;
            }
            return Regex.Replace(value, "(?<!^)([A-Z][a-z]|(?<=[a-z])[A-Z])", "-$1", RegexOptions.Compiled).Trim().ToLower();
        }
        #endregion

        #endregion

    }
    #endregion

}
